import 'dart:convert';
import 'dart:async';
import 'package:http/http.dart' as http;
import '../config/app_config.dart';
import 'auth_service.dart';
import '../models/api_response.dart';
import 'package:flutter/foundation.dart';
import 'dart:typed_data';

/// API 服务类
/// 用于处理所有的 API 请求
class ApiService {
  /// 基础 URL
  static String get baseUrl => AppConfig.apiServerUrl;

  /// 默认超时时间
  static const Duration defaultTimeout = Duration(seconds: 30);

  /// 默认重试次数
  static const int defaultRetries = 3;

  /// 发送 GET 请求
  static Future<ApiResponse<T>> get<T>(
    String path, {
    Map<String, String>? queryParams,
    T Function(dynamic)? fromJson,
    Duration timeout = defaultTimeout,
    Map<String, String>? additionalHeaders,
  }) async {
    return _sendRequest<T>(
      'GET',
      path,
      queryParams: queryParams,
      fromJson: fromJson,
      timeout: timeout,
      additionalHeaders: additionalHeaders,
    );
  }

  /// 发送 POST 请求
  static Future<ApiResponse<T>> post<T>(
    String path, {
    Map<String, String>? queryParams,
    dynamic body,
    T Function(dynamic)? fromJson,
    Duration timeout = defaultTimeout,
    Map<String, String>? additionalHeaders,
  }) async {
    return _sendRequest<T>(
      'POST',
      path,
      queryParams: queryParams,
      body: body,
      fromJson: fromJson,
      timeout: timeout,
      additionalHeaders: additionalHeaders,
    );
  }

  /// 发送 PUT 请求
  static Future<ApiResponse<T>> put<T>(
    String path, {
    Map<String, String>? queryParams,
    dynamic body,
    T Function(dynamic)? fromJson,
    Duration timeout = defaultTimeout,
    Map<String, String>? additionalHeaders,
  }) async {
    return _sendRequest<T>(
      'PUT',
      path,
      queryParams: queryParams,
      body: body,
      fromJson: fromJson,
      timeout: timeout,
      additionalHeaders: additionalHeaders,
    );
  }

  /// 发送 DELETE 请求
  static Future<ApiResponse<T>> delete<T>(
    String path, {
    Map<String, String>? queryParams,
    dynamic body,
    T Function(dynamic)? fromJson,
    Duration timeout = defaultTimeout,
    Map<String, String>? additionalHeaders,
  }) async {
    return _sendRequest<T>(
      'DELETE',
      path,
      queryParams: queryParams,
      body: body,
      fromJson: fromJson,
      timeout: timeout,
      additionalHeaders: additionalHeaders,
    );
  }

  /// 上传文件
  static Future<ApiResponse<T>> uploadFile<T>(
    String path, {
    required dynamic fileSource,
    String? fileName,
    Map<String, String>? fields,
    T Function(dynamic)? fromJson,
    Duration timeout = const Duration(minutes: 10),
    Map<String, String>? additionalHeaders,
  }) async {
    try {
      final uri = Uri.parse('$baseUrl$path');
      final request = http.MultipartRequest('POST', uri);

      // 添加认证头和其他头信息
      final headers = await _getHeaders(additionalHeaders);
      request.headers.addAll(headers);

      // 添加文件
      if (kIsWeb) {
        if (fileSource is Uint8List) {
          request.files.add(
            http.MultipartFile.fromBytes(
              'file',
              fileSource,
              filename: fileName ?? 'file',
            ),
          );
        } else {
          throw Exception('Web平台上传文件需要提供字节数据');
        }
      } else {
        if (fileSource is String) {
          request.files.add(
            await http.MultipartFile.fromPath(
              'file',
              fileSource,
              filename: fileName,
            ),
          );
        } else {
          throw Exception('非Web平台上传文件需要提供文件路径');
        }
      }

      // 添加额外的字段
      if (fields != null) {
        request.fields.addAll(fields);
      }

      // 发送请求
      final streamedResponse = await request.send().timeout(timeout);
      final response = await http.Response.fromStream(streamedResponse);

      return _handleResponse<T>(response, fromJson);
    } catch (e) {
      debugPrint('文件上传错误: $e');
      rethrow;
    }
  }

  /// 发送请求的通用方法
  static Future<ApiResponse<T>> _sendRequest<T>(
    String method,
    String path, {
    Map<String, String>? queryParams,
    dynamic body,
    T Function(dynamic)? fromJson,
    Duration timeout = defaultTimeout,
    Map<String, String>? additionalHeaders,
    int retryCount = defaultRetries,
  }) async {
    try {
      // 构建完整的 URL
      final uri = Uri.parse(
        '$baseUrl$path',
      ).replace(queryParameters: queryParams);
      debugPrint('发送 $method 请求到: $uri'); // 调试日志

      // 获取请求头
      final headers = await _getHeaders(additionalHeaders);
      debugPrint('请求头: $headers'); // 调试日志

      // 准备请求体
      String? encodedBody;
      if (body != null) {
        encodedBody = json.encode(body);
        debugPrint('请求体: $encodedBody'); // 调试日志
      }

      // 发送请求
      late http.Response response;
      switch (method) {
        case 'GET':
          response = await http.get(uri, headers: headers).timeout(timeout);
          break;
        case 'POST':
          response = await http
              .post(uri, headers: headers, body: encodedBody)
              .timeout(timeout);
          break;
        case 'PUT':
          response = await http
              .put(uri, headers: headers, body: encodedBody)
              .timeout(timeout);
          break;
        case 'DELETE':
          response = await http
              .delete(uri, headers: headers, body: encodedBody)
              .timeout(timeout);
          break;
        default:
          throw Exception('不支持的 HTTP 方法: $method');
      }

      debugPrint('响应状态码: ${response.statusCode}'); // 调试日志
      debugPrint('响应体: ${response.body}'); // 调试日志

      // 处理 401 错误（认证失败）
      if (response.statusCode == 401 && retryCount > 0) {
        final refreshed = await AuthService.handleAuthError(
          response.statusCode,
        );
        if (refreshed) {
          // 重试请求
          return _sendRequest<T>(
            method,
            path,
            queryParams: queryParams,
            body: body,
            fromJson: fromJson,
            timeout: timeout,
            additionalHeaders: additionalHeaders,
            retryCount: retryCount - 1,
          );
        }
        throw Exception('认证失败，请重新登录');
      }

      return _handleResponse<T>(response, fromJson);
    } catch (e) {
      debugPrint('请求错误: $e'); // 调试日志
      if (e is http.ClientException) {
        throw Exception('网络连接错误: ${e.message}');
      } else if (e is TimeoutException) {
        throw Exception('请求超时');
      }
      rethrow;
    }
  }

  /// 获取请求头
  static Future<Map<String, String>> _getHeaders([
    Map<String, String>? additionalHeaders,
  ]) async {
    final authHeaders = await AuthService.getAuthHeaders();
    final headers = {
      ...authHeaders,
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      if (additionalHeaders != null) ...additionalHeaders,
    };
    return headers;
  }

  /// 处理响应数据
  static ApiResponse<T> _handleResponse<T>(
    http.Response response,
    T Function(dynamic)? fromJson,
  ) {
    try {
      debugPrint('ApiService - 处理响应 - 状态码: ${response.statusCode}');
      final bodyBytes = response.bodyBytes;
      final bodyString = utf8.decode(bodyBytes);
      debugPrint('ApiService - 处理响应 - 响应体: $bodyString');

      if (bodyString.isEmpty) {
        debugPrint('ApiService - 处理响应 - 响应体为空');
        throw Exception('服务器返回空响应');
      }

      final json = jsonDecode(bodyString) as Map<String, dynamic>;
      debugPrint('ApiService - 处理响应 - 解析后的JSON: $json');

      final apiResponse = ApiResponse.fromJson(json, fromJson);
      debugPrint(
        'ApiService - 处理响应 - API响应对象: {code: ${apiResponse.code}, message: ${apiResponse.message}, hasData: ${apiResponse.data != null}}',
      );

      return apiResponse;
    } catch (e, stackTrace) {
      debugPrint('ApiService - 处理响应 - 解析错误: $e');
      debugPrint('错误堆栈: $stackTrace');
      rethrow;
    }
  }
}
